# 2.1导入蓝图对象
import random
import re
from datetime import datetime

from flask import current_app, jsonify
from flask import request, make_response
from flask import session
from info import redis_store, constants, db
from info.libs.yuntongxun.sms import CCP
from info.models import User
from info.utils.captcha.captcha import captcha
from info.utils.response_code import RET
from . import passport_blue


# 2.2使用蓝图对象实现路由
#退出账号登陆
@passport_blue.route('/logout',methods=['POST'])
def logout():
    #清除session中对应的登陆信息
    session.pop('user_id', None)
    session.pop('nick_name', None)
    session.pop('mobile', None)
    session.pop('is_admin', None)

    #返回结果
    return jsonify(errno=RET.OK,errmsg='退出成功')

# 登陆用户
# 请求方式：POST
# URL:ｌｏｇｉｎ
# 参数:mobile，password
@passport_blue.route('/login',methods=['POST'])
def login():
    #获取参数（手机号，密码）
    json_dict = request.json
    mobile = json_dict.get('mobile')
    password = json_dict.get('password')

    #校验参数（完整性，手机号）
    if not all([mobile,password]):
        return jsonify(errno=RET.PARAMERR,errmsg='参数不全')

    if not re.match(r'1[3456789][0-9]{9}',mobile):
        return jsonify(errno=RET.DATAERR,errmsg='手机格式错误')

    #判断数据库是否有该手机号
    try:
        user = User.query.filter_by(mobile=mobile).first()
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR,errmsg='查询数据库失败')


    #判断密码是否正确
    if not user or not user.check_passowrd(password):
        return jsonify(errno=RET.DATAERR,errmsg='用户名不存在或密码错误')

    #设置当前登陆的时间为当前时间
    user.last_login = datetime.now()

    # try:
    #     db.session.commit()
    # except Exception as e:
    #     current_app.logger.error(e)
    #     db.session.rollback()

    # 设置用户登陆--session
    session['user_id'] = user.id
    session['nike_name'] = user.nick_name
    session['moblie'] = user.mobile

    # 　返回数据
    return jsonify(errno=RET.OK, errmsg='登陆成功')



# 注册用户
# 请求方式：POST
# URL:redister
# 参数:mobile.sms_code,password

@passport_blue.route('/register',methods=['POST'])
def register():
    #　获取参数
    #获取参数（手机号，验证码，密码）
    json_dict = request.json
    mobile = json_dict.get('mobile')
    sms_code = json_dict.get('sms_code')
    password = json_dict.get('password')
    #　校验参数
    #校验参数（完整性，手机号）
    if not all(['mobile','sms_code','password']):
        return jsonify(errno=RET.PARAMERR,errmsg='参数不全')
    if not re.match(r'1[3456789][0-9]{9}',mobile):
        return jsonify(errno=RET.DATAERR,errmsg='手机格式错误')

    #　逻辑处理
    #从ｒｅｄｉｓ中获取短信验证码
    try:
        real_sms_code = redis_store.get("SMS_" + mobile)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR,errmsg='查询数据库失败')
    if not real_sms_code:
        return jsonify(errno=RET.NODATA,errmsg='短信验证码过期或手机号填写错误')

    # 对比验证码，对比失败返回数据
    if real_sms_code != sms_code:
        return jsonify(errno=RET.DATAERR,errmsg='短信验证码填写错误')

    # 对比成功，删除短信验证码
    try:
        redis_store.delete("SMS_" + mobile)
    except Exception as e:
        current_app.logger.error(e)
        #从用户角度来说，如果出错了，可以不用返回ｊｓｏｎ数据
        #return jsonify(errno=RET.DBERR,errmsg='删除验证码失败')

    #对比成功，注册用户
    #手机号是否注册过
    try:
        user = User.query.filter_by(mobile=mobile).first()
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR,errmsg='查询mysql用户失败')
    if user:
        return jsonify(errno=RET.DATAEXIST,errmsg='手机号已经注册')
    # 创建ｕｓｅｒ对象
    user = User()
    user.nick_name = mobile
    user.mobile = mobile

    #实际开发中，如果对模型数据进行处理，不会放在视图函数中，而是模型中进行
    user.password = password
    #添加到mysql数据库
    try:
        db.session.add(user)
        db.session.commit()
    except Exception as e:
        #数据修改操作，失败了需要回滚
        db.session.rollback()
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR,errmsg='保存mysql数据库失败')

    #设置用户登陆--session
    session['user_id'] = user.id
    session['nikename'] = user.nick_name
    session['moblie'] = user.mobile

    #　返回数据
    return jsonify(errno=RET.OK,errmsg='注册成功')


# 获取短信验证码
# 请求方式为ｐｏｓｔ
# ｕｒｌ:sms_code?mobile=13xxxxxxx&image_code=abcd&image_code_id=xxxx
# 参数：mobile,image_code,image_code_ide


@passport_blue.route('/sms_code', methods=['POST'])
def get_sms_code():
    # 1.获取数据
    # １．１获取参数(手机号，图像验证码，图像验证码ｉｄ）
    # 局部数据更新需要使用ｊｓｏｎ传输数据
    # ｒｅｑｕｅｓｔ。ｄａｔａ返回的是字符串数据
    # json.loads(request.data)
    json_data = request.json
    mobile = json_data.get('mobile')
    image_code = json_data.get('image_code')
    image_code_id = json_data.get('image_code_id')

    #2.校验数据
    #验证数据（完整性，正则验证手机号）
    if not all([mobile,image_code,image_code_id]):
        return jsonify(errno= RET.PARAMERR,errmsg= '参数不全')

    if not re.match(r'1[3456789][0-9]{9}',mobile):
        return jsonify(errno= RET.DATAERR,errmsg= '手机号格式错误')

    #3.逻辑处理
    #从ｒｅｄｉｓ获取图片验证码
    try:
        real_image_code = redis_store.get('ImageCodeID' + image_code_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR,errmsg= 'redis查询失败')

    #查询redis&mysql 都需要做判断空的处理
    if not real_image_code:
        return jsonify(errno= RET.NODATA,errmsg= '验证码过期')

    # 4.将两个数据进行对比处理，如果对比失败，返回ｊｓｏｎ数据
    # 为了完善逻辑，图片验证码从ｒｅｄｉｓ获取之后就删除
    try:
        redis_store.delete('ImageCodeID' + image_code_id)
    except Exception as e:
        current_app.logger.error(e)
        #可删可不删
        return jsonify(errno=RET.DBERR,errmsg='redis删除失败')

    if real_image_code.lower() != image_code.lower():
        # 对比失败，返回ｊｓｏｎ数据
        return jsonify(errno= RET.DATAERR,errmsg= '验证码错误')

    #图像验证码对比成功，查看手机号是否注册
    try:
        user = User.query.filter_by(mobile=mobile).first()
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg='查询mysql用户失败')
    if user:
        return jsonify(errno=RET.DATAEXIST, errmsg='手机号已经注册')

    # ５对比成功，返回短信验证码
    sms_code_str = '%06d'%random.randint(0,999999)

    # 6保存到redis中
    try:
        redis_store.set("SMS_" + mobile, sms_code_str, constants.SMS_CODE_REDIS_EXPIRES)
    except Exception as e:
        current_app.logger.error(e)
        #保存短信验证码失败
        return jsonify(errno= RET.DBERR,errmsg= '保存短信验证码失败')

    #7调用云通讯发短信
    result = CCP().send_template_sms(mobile, [sms_code_str, 5], 1)
    if result != 0:
        return jsonify(errno= RET.THIRDERR,errmsg= '短信发送失败')

    #4返回数据
    #发送成功，返回ｊｓｏｎ数据
    return jsonify(errno= RET.OK,errmsg= '短信发送成功')



#获取图形验证码
#ＵＲＬ：ｉｍａｇｅ／ｃｏｄｅ
#请求方式：ＧＥＴ
#参数：ｉｍａｇｅ_code_id
@passport_blue.route('/image_code')
def get_image_code():
    #１获取参数
    image_code_id = request.args.get('image_code_id')
    #２生成验证码图像
    name,text,image_data = captcha.generate_captcha()
    #３保存ｒｅｄｉｓ  try
    try:
        redis_store.set('ImageCodeID' + image_code_id,text,300)
    except Exception as e:
        #保存日志
        current_app.logger.error(e)
        #返回错误信息--json格式　
        #如果要全局更新网页，可以渲染模板
        #如果只是局部更新，前后段用json传输即可
        return jsonify(errno=4001,errmsg='保存redis出错')
    #４返回图像
    response = make_response(image_data)
    response.headers['Content-Type'] = 'image/jpg'
    return response

